/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-1-4 21:53:17
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#ifndef INCLUDE_BASE_XTHREAD_H_
#define INCLUDE_BASE_XTHREAD_H_

#include "baseheader.h"

#define SLEEP_MS(ms)    \
    do { \
        struct timeval tv; \
        tv.tv_sec = (ms) / 1000; \
        tv.tv_usec = ( (ms) % 1000 ) * 1000; \
        select( 0, NULL, NULL, NULL, &tv ); \
    } while( 0 )

BEG_NS_SMART

class threadbase_t
{
public:
	threadbase_t();
	virtual ~threadbase_t();

	virtual int start();
	virtual int stop();

public:
	unsigned int get_tid() const { return (unsigned int)m_tid; }
	bool isRunning() const { return m_running; }
protected:
	virtual int run() = 0;	//if return < 0 then exit this thread
protected:
	pthread_t m_tid;
	bool m_running;
private:
	static void* threadFunc(void* arg);
};


template<class T>
class thread_t : public threadbase_t
{
public:
	typedef int (T::*func_type_t)(threadbase_t* thr);
	thread_t(func_type_t func = NULL, T* obj = NULL) : m_func(func), m_obj(obj) { }
	virtual ~thread_t() { stop(); }

	inline void setRunner(func_type_t func, T* obj) {
		m_func = func;
		m_obj = obj;
	}

protected:
	virtual inline int run() {
		if(m_func == NULL) {
			return -1;
		}
		return (m_obj->*m_func)(this);
	}
protected:
	func_type_t m_func;
	T* m_obj;
};


typedef int (*g_func_type_t)(void* arg, threadbase_t* thr);
template<>
class thread_t<void> : public threadbase_t
{
public:
	thread_t(g_func_type_t func = NULL, void* arg = NULL) : m_func(func), m_arg(arg) { }
	virtual ~thread_t() { stop(); }

	inline void setRunner(g_func_type_t func, void* arg) {
		m_func = func;
		m_arg = arg;
	}

protected:
	virtual inline int run() {
		if(m_func == NULL) {
			return -1;
		}
		return m_func(m_arg, this);
	}

protected:
	g_func_type_t m_func;
	void* m_arg;
};

END_NS_SMART

#endif //~INCLUDE_BASE_XTHREAD_H_
